﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.Web;
using UDS.Components;

namespace UDS.Entity
{
    public class Flow
    {
        #region properties

        public int ID
        {
            get;
            set;
        }

        /// <summary>
        /// Get or set the id of the referenced <see cref="FlowStyle"/>.
        /// </summary>
        public int StyleID
        {
            get;
            set;
        }

        /// <summary>
        /// Get the name of the referenced <see cref="FlowStyle"/>.
        /// </summary>
        public string StyleName
        {
            get;
            private set;
        }

        public string Name
        {
            get;
            set;
        }

        public DateTime TimeCreated
        {
            get;
            set;
        }

        public string Creator
        {
            get;
            set;
        }

        public string Description
        {
            get;
            set;
        }

        #endregion

        #region methods

        /// <summary>
        /// Get all existing flows.
        /// </summary>
        public static IList<Flow> GetAllFlows()
        {
            var parameters = new[]
            {
                Database.MakeInParam("@FlowID", SqlDbType.Int, 4, 0),
            };

            var list = new List<Flow>();
            var db = new Database();
            using (var dr = db.RunDataReader("dbo.sproc_Flow_GetFlow_V2", parameters))
            {
                while (dr.Read())
                {
                    list.Add(ReadFlow(dr));
                }
            }
            return list;
        }

        /// <summary>
        /// Get the information of the specified flow.
        /// </summary>
        public static Flow GetFlow(int id)
        {
            if (id <= 0)
            {
                throw new ArgumentOutOfRangeException("id", "The flow id must be greater than zero.");
            }

            var parameters = new[]
            {
                Database.MakeInParam("@FlowID", SqlDbType.Int, 4, id)
            };

            var db = new Database();
            using (var dr = db.RunDataReader("dbo.sproc_Flow_GetFlow_V2", parameters))
            {
                if (dr.Read())
                {
                    return ReadFlow(dr);
                }
            }
            return null;
        }

        /// <summary>
        /// Get the formatted title of the given flow.
        /// </summary>
        public static string GetFlowTitle(int id)
        {
            Flow f = GetFlow(id);
            if (f != null)
            {
                var sb = new StringBuilder();
                sb.Append("<span class=\"flow_title\" title=\"");
                sb.Append(HttpUtility.HtmlAttributeEncode(f.Description));
                sb.Append("\">");
                sb.Append(HttpUtility.HtmlEncode(f.Name));
                sb.Append("</span>");

                return sb.ToString();
            }

            return null;
        }

        public static string GetFlowHeadline(int flowId)
        {
            var parameters = new[]
            {
                Database.MakeInParam("@FlowID", SqlDbType.Int, 4, flowId)
            };

            var db = new Database();
            using (var dr = db.RunDataReader("dbo.sproc_Flow_GetStyleHead_V2", parameters))
            {
                if (dr.Read())
                {
                    return string.Concat(Convert.ToString(dr["Flow_Name"]), " (流水号:", ((int)dr["Times"]).ToString(), ")");
                }
            }
            return string.Empty;
        }

        /// <summary>
        /// 添加流程
        /// </summary>
        /// <param name="FlowName">流程名</param>
        /// <param name="FlowRemark">流程简介</param>
        /// <param name="Builder">流程制定者</param>
        /// <param name="StyleID">流程自定义表单</param>
        public static int AddFlow(string FlowName, string FlowRemark, string Builder, int StyleID)
        {
            var parameters = new[]
            {
                Database.MakeInParam("@FlowName", SqlDbType.NVarChar, 300, FlowName),
                Database.MakeInParam("@FlowRemark", SqlDbType.NText, 3000, FlowRemark),
                Database.MakeInParam("@Builder", SqlDbType.NVarChar, 300, Builder),
                Database.MakeInParam("@StyleID", SqlDbType.Int, 4, StyleID)
            };

            using (var db = new Database())
            {
                return db.RunProc("dbo.sproc_Flow_AddFlow_V2", parameters);
            }
        }

        /// <summary>
        /// 删除流程
        /// </summary>
        /// <param name="id">被删除的流程ID</param>
        public static int DeleteFlow(int id)
        {
            var parameters = new[]
            {
                Database.MakeInParam("@FlowID", SqlDbType.Int, 4, id)
            };

            using (var db = new Database())
            {
                return db.RunProc("dbo.sproc_Flow_DeleteFlow_V2", parameters);
            }
        }

        /// <summary>
        /// 修改流程
        /// </summary>
        /// <param name="FlowID">流程ID</param>
        /// <param name="FlowName">流程名</param>
        /// <param name="FlowRemark">流程简介</param>
        /// <param name="Builder">流程制定者</param>
        /// <param name="StyleID">流程自定义表单</param>
        public static int UpdateFlow(int FlowID, string FlowName, string FlowRemark, string Builder, int StyleID)
        {
            var parameters = new[]
            {
                Database.MakeInParam("@FlowID", SqlDbType.Int, 4, FlowID),
                Database.MakeInParam("@FlowName", SqlDbType.NVarChar, 300, FlowName),
                Database.MakeInParam("@FlowRemark", SqlDbType.NText, 3000, FlowRemark),
                Database.MakeInParam("@Builder", SqlDbType.NVarChar, 300, Builder),
                Database.MakeInParam("@StyleID", SqlDbType.Int, 4, StyleID)
            };

            using (var db = new Database())
            {
                return db.RunProc("dbo.sproc_Flow_UpdateFlow_V2", parameters);
            }
        }

        #endregion methods

        #region help methods

        private static Flow ReadFlow(IDataReader dr)
        {
            var f = new Flow();
            f.ID = (int)dr["Flow_ID"];
            f.StyleID = (int)dr["Style_ID"];
            f.StyleName = Convert.ToString(dr["Style_Name"]);
            f.Name = Convert.ToString(dr["Flow_Name"]);
            f.TimeCreated = Utility.ReadSQLDate(dr["Build_Date"]);
            f.Creator = Convert.ToString(dr["Builder"]);
            f.Description = Utility.ReadString(dr["Remark"]);

            return f;
        }

        #endregion help methods
    }
}
